package Decompression;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;


public class DecompressionManager {
    public static void decompressFile(File fileDecompress) throws IOException {
        //File fileDecompress = new File(filePath);
        String contentOfFile = getContents(fileDecompress);
        //System.out.println(contentOfFile);
        
        // Store huffman code of each caracter
        String[] charFreqsStr = new String[256];
        String codeCar = "";
        String codeHuff = "";
        String newString = "";
        String strHuffman = "";
        int byteExtra = 0;
        boolean boolHuff = false;
        
        // Retrieve Header information
        for (int i = 0; i < contentOfFile.length(); i++) {
            if (contentOfFile.charAt(i) == '/') {
                boolHuff = true;
            }
            else if (contentOfFile.charAt(i) == ';') {
                charFreqsStr[Integer.parseInt(codeCar)] = codeHuff;
                boolHuff = false;
                codeCar = "";
                codeHuff = "";
            }
            else {
                if (contentOfFile.charAt(i) == '#') {
                    byteExtra = Integer.parseInt(contentOfFile.substring(i + 1, i + 2));
                    newString = contentOfFile.substring(i + 3, contentOfFile.length() - 1);
                    i = contentOfFile.length();
                }
                else {
                    if (boolHuff == false) {
                        codeCar = codeCar + contentOfFile.charAt(i);
                    }
                    else {
                        codeHuff = codeHuff + contentOfFile.charAt(i);
                    }
                }   
            }
        }
        
        
        
        byte[] arrByte = newString.getBytes();
        byte byteValue;
        String temp = "";
        
        
        for (int i = 0; i < arrByte.length; i++) {

            byteValue = arrByte[i];
            for (int j = 0; j < 8; j++) {
                temp = (byteValue & 1) + temp;
                byteValue = (byte)(byteValue >> 1);
            }
            strHuffman = strHuffman + temp;
            temp = "";
        }
        strHuffman = strHuffman.substring(0, strHuffman.length() - byteExtra);
        
        
        
        String cHuff = "";
        String newContents = "";
        boolean chiffreTrouver = false;
        int j = 0;
        int codeChar = 0;
        
        for (int i = 0; i < strHuffman.length(); i++) {
            cHuff = cHuff + String.valueOf(strHuffman.charAt(i));
            chiffreTrouver = false;
            while (!chiffreTrouver && j < charFreqsStr.length) {
                if (charFreqsStr[j] != null && cHuff.length() <= charFreqsStr[j].length()) {
                    if (charFreqsStr[j].substring(0, cHuff.length()).compareTo(cHuff) == 0) {
                        chiffreTrouver = true;
                        codeChar = j;
                    }
                    else {
                        j++;
                    }
                }
                else {
                    j++;
                }
                
            }
            if (j == charFreqsStr.length) {
                newContents = newContents + String.valueOf((char)codeChar);
                cHuff = "";
                j = 0;
                i--;
            }
        }
        //System.out.println("Contenu extrait : " + newContents);
        
        String newFileName = fileDecompress.getParent() + File.separator + fileDecompress.getName().substring(0, fileDecompress.getName().lastIndexOf(".")) + "(decompressed).txt";
        File newFile = new File(newFileName);
        FileOutputStream writer = new FileOutputStream(newFile);
        writer.write(newContents.getBytes());
        writer.close();
        //System.out.println(String.valueOf((char)70));
    }
    
    public static String getContents(File aFile) {
        // ...checks on aFile are elided
        StringBuilder contents = new StringBuilder();

        try {
            // use buffering, reading one line at a time
            // FileReader always assumes default encoding is OK!
            BufferedReader input = new BufferedReader(new FileReader(aFile));
            try {
                String line = null; // not declared within while loop
                /*
                 * readLine is a bit quirky : it returns the content of a line
                 * MINUS the newline. it returns null only for the END of the
                 * stream. it returns an empty String if two newlines appear in
                 * a row.
                 */
                while ((line = input.readLine()) != null) {
                    contents.append(line);
                    contents.append(System.getProperty("line.separator"));
                }
            } finally {
                input.close();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        return contents.toString();
    }
    
}
